🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / feature / wifi-provision / src / commonTest / kotlin / org / meshtastic / feature / wifiprovision / domain / NymeaPacketCodecTest.kt
Displaying Raw • Download
feature/wifi-provision/src/commonTest/kotlin/org/meshtastic/feature/wifiprovision/domain/NymeaPacketCodecTest.kt renovate/actions-setup-java-5.x (f17e586c) Text, 6.47 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tf0883e@fileTb4b4b4:Te6edf3SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72package T7ee787org.meshtastic.feature.wifiprovision.domain
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertNull
Tff7b72import T7ee787kotlin.test.assertTrue
Tff7b72class T56d364NymeaPacketCodecTest Tb4b4b4{
T8b949e// -----------------------------------------------------------------------
T8b949e// encode()
T8b949e// -----------------------------------------------------------------------
Tf0883e@Test
Tff7b72fun Td2a8ff`encode appends newline terminator`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Ta5d6ff"Ta5d6ff{}Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3reassembled Tff7b72= Te6edf3packetsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3assertTrueTb4b4b4(Te6edf3reassembledTb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffEncoded payload must end with newlineTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode short message fits in single packet`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:4}Ta5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4, Ta5d6ff"Ta5d6ffShort JSON should fit in a single packetTa5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:4}Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4, Te6edf3packetsTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode long message splits across multiple packets`Tb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// 20-byte max packet size (default). Use a payload that exceeds it.
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff5T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3maxPacketSize Tff7b72= T79c0ff2T79c0ff0Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3packetsTb4b4b4.Te6edf3size Tff7b72> T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffLong payload should be splitTa5d6ff"Tb4b4b4)
Te6edf3packetsTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3packet Tff7b72-Tff7b72> Te6edf3assertTrueTb4b4b4(Te6edf3packetTb4b4b4.Te6edf3size Tff7b72<Tff7b72= T79c0ff2T79c0ff0Tb4b4b4, Ta5d6ff"Ta5d6ffEach packet must be ≤ maxPacketSizeTa5d6ff"Tb4b4b4) Tb4b4b4}
T8b949e// Reassemble and verify content
Tff7b72val Te6edf3reassembled Tff7b72= Te6edf3packetsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Te6edf3json Tff7b72+ Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4, Te6edf3reassembledTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode boundary payload exactly fills packets`Tb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// 19 chars + 1 newline = 20 bytes = exactly 1 packet at maxPacketSize=20
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff1T79c0ff9Tb4b4b4)
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3maxPacketSize Tff7b72= T79c0ff2T79c0ff0Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff2T79c0ff0Tb4b4b4, Te6edf3packetsTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3sizeTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode boundary payload one byte over splits into two packets`Tb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// 20 chars + 1 newline = 21 bytes → 2 packets at maxPacketSize=20
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff2T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3maxPacketSize Tff7b72= T79c0ff2T79c0ff0Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff2T79c0ff0Tb4b4b4, Te6edf3packetsTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3packetsTff7b72[T79c0ff1Tff7b72]Tb4b4b4.Te6edf3sizeTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode empty string produces single packet with just newline`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4, Te6edf3packetsTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode custom maxPacketSize is respected`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"Ta5d6ffABCDEFGHIJTa5d6ff" T8b949e// 10 chars + 1 newline = 11 bytes
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3maxPacketSize Tff7b72= T79c0ff4Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff3Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4) T8b949e// 4 + 4 + 3
Te6edf3packetsTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3assertTrueTb4b4b4(Tffa657itTb4b4b4.Te6edf3size Tff7b72<Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Te6edf3json Tff7b72+ Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4) Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4)
Tb4b4b4}
T8b949e// -----------------------------------------------------------------------
T8b949e// Reassembler
T8b949e// -----------------------------------------------------------------------
Tf0883e@Test
Tff7b72fun Td2a8ff`reassembler returns complete message on single feed with terminator`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3result Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:4}Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:4}Ta5d6ff"Tb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`reassembler buffers partial data and returns null`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:Ta5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff4}Ta5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`reassembler completes when terminator arrives in later chunk`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:Ta5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff4}Ta5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3result Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ff{Ta5d6ff\"Ta5d6ffcTa5d6ff\"Ta5d6ff:4}Ta5d6ff"Tb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`reassembler handles multiple messages sequentially`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3first Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6fffirstTa5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6fffirstTa5d6ff"Tb4b4b4, Te6edf3firstTb4b4b4)
Tff7b72val Te6edf3second Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ffsecondTa5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffsecondTa5d6ff"Tb4b4b4, Te6edf3secondTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`reassembler reset clears buffered data`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6ffpartialTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3reassemblerTb4b4b4.Te6edf3resetTb4b4b4(Tb4b4b4)
T8b949e// After reset, the partial data is gone — new message starts fresh
Tff7b72val Te6edf3result Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Ta5d6ff"Ta5d6fffreshTa5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6fffreshTa5d6ff"Tb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode and reassembler round-trip`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"""Ta5d6ff{Ta5d6ff"Ta5d6ffcTa5d6ff"Ta5d6ff:1,Ta5d6ff"Ta5d6ffpTa5d6ff"Ta5d6ff:{Ta5d6ff"Ta5d6ffeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffMyNetworkTa5d6ff"Ta5d6ff,Ta5d6ff"Ta5d6ffpTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffsecret123Ta5d6ff"Ta5d6ff}}Ta5d6ff"""
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4)
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3resultTb4b4b4: Tffa657String? Tff7b72= Tff7b72null
Tff7b72for Tb4b4b4(Te6edf3packet Tff7b72in Te6edf3packetsTb4b4b4) Tb4b4b4{
Te6edf3result Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`encode and reassembler round-trip with small packet size`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3json Tff7b72= Ta5d6ff"""Ta5d6ff{Ta5d6ff"Ta5d6ffcTa5d6ff"Ta5d6ff:0,Ta5d6ff"Ta5d6ffrTa5d6ff"Ta5d6ff:0,Ta5d6ff"Ta5d6ffpTa5d6ff"Ta5d6ff:[{Ta5d6ff"Ta5d6ffeTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffTestNetTa5d6ff"Ta5d6ff,Ta5d6ff"Ta5d6ffmTa5d6ff"Ta5d6ff:Ta5d6ff"Ta5d6ffAA:BBTa5d6ff"Ta5d6ff,Ta5d6ff"Ta5d6ffsTa5d6ff"Ta5d6ff:85,Ta5d6ff"Ta5d6ffpTa5d6ff"Ta5d6ff:1}]}Ta5d6ff"""
Tff7b72val Te6edf3packets Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3maxPacketSize Tff7b72= T79c0ff8Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3packetsTb4b4b4.Te6edf3size Tff7b72> T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffShould require multiple packets with small MTUTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3reassembler Tff7b72= Te6edf3NymeaPacketCodecTb4b4b4.Te6edf3ReassemblerTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3resultTb4b4b4: Tffa657String? Tff7b72= Tff7b72null
Tff7b72for Tb4b4b4(Te6edf3packet Tff7b72in Te6edf3packetsTb4b4b4) Tb4b4b4{
Te6edf3result Tff7b72= Te6edf3reassemblerTb4b4b4.Te6edf3feedTb4b4b4(Te6edf3packetTb4b4b4)
Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Te6edf3jsonTb4b4b4, Te6edf3resultTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.07s